package org.agilelang.generator.webservices.php;

/*
 AgileLang - A fourth generation language(http://www.agilelang.org).

 Copyright (C) 2013 Roderick Cusirramos (roderick20@hotmail.com)

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.agilelang.mvc.Generator;
import org.agilelang.mvc.IModel;
import org.agilelang.object.Model;
import org.agilelang.object.attributes.Attribute;
import org.agilelang.object.attributes.Reference;

public class GModel extends Generator implements IModel {

    public GModel(String path, List<Model> listModel) {
        this.path = path;
        this.models = listModel;
        this.setTemplate2("webservices/php");
        this.template = "bootstrap";
    }

    public void process() {
        int t = models.size();

        for (int i = 0; i < t; i++) {
            boolean ref = false;
            Model model = models.get(i);

            String list_atrrs_select = "id";
            String list_atrrs_create = "";
            String list_atrrs_create_bind = "";
            String list_atrrs_create_values = "";
            String list_atrrs_create_param = "";
            String list_atrrs_update = "";
            String list_atrrs_update_bind = "";
            String list_atrrs_find = "";

            String query_select = "";
            String query_select_find = "";
            String query_select_param_model = "";
            String query_select_param_model_array = "";
            String query_select_param_references = "";
            String query_select_param_references_array = "";

            String query_select_param_references_post = "";
            String query_select_inner_join = "";
            String query_select_where = "";

            String find_references = "";
            // SELECT param_model , param_references FROM model INNER JOIN references  WHERE references = model
            int tr = model.references.size();
            for (int j = 0; j < tr; j++) {
                String query_select_param_references_array_tmp = "";
                String query_select_param_references_tmp = "";
                Reference reference = model.references.get(j);
                Model model2 = this.getModelByName(reference.model_reference);
                List<Attribute> listattr2 = model2.attributes;
                int ta2 = listattr2.size();
                for (int jj = 0; jj < ta2; jj++) {
                    Attribute attr = listattr2.get(jj);
                    query_select_param_references_tmp += ", " + this.setPluralize(model2.name).toLowerCase() + "." + attr.name + " " + this.setPluralize(model2.name).toLowerCase() + attr.name;
                    query_select_param_references_array_tmp += ", '" + attr.name + "' => $row['" + this.setPluralize(model2.name).toLowerCase() + attr.name + "']";

                }
                query_select_param_references += this.setPluralize(model2.name).toLowerCase() + ".id " + this.setPluralize(model2.name).toLowerCase() + "id " + query_select_param_references_tmp +" , ";
                query_select_param_references_array_tmp = "'id' => $row['" + this.setPluralize(model2.name).toLowerCase() + "id']" + query_select_param_references_array_tmp;
                query_select_param_references_array += "$" + this.setPluralize(model2.name).toLowerCase() + " = array(" + query_select_param_references_array_tmp + ");\n";


                query_select_inner_join += " INNER JOIN " + this.setPluralize(model2.name).toLowerCase() + " " + this.setPluralize(model2.name).toLowerCase();
                if (tr > 1) {
                    query_select_where += "" + this.setPluralize(model.name).toLowerCase() + "." + reference.foreign_key + " = " + this.setPluralize(model2.name).toLowerCase() + ".id AND ";
                } else {
                    query_select_where += "" + this.setPluralize(model.name).toLowerCase() + "." + reference.foreign_key + " = " + this.setPluralize(model2.name).toLowerCase() + ".id";

                }

                query_select_param_references_post += ", " + "'" + this.setPluralize(model2.name).toLowerCase() + "' => $" + this.setPluralize(model2.name).toLowerCase() + "";

                String file = readStreamTpl("_find_ref.tpl");
                file = file.replace("//namefunction//", this.setSingularize(reference.model_reference));
                file = file.replace("//query_select//", "SELECT id, " + reference.field_reference + " FROM " + this.setPluralize(reference.model_reference).toLowerCase());
                file = file.replace("//result//", "$posts[] = array('" + reference.model_reference.toLowerCase() + "' => array('id' => $row['id'], '" + reference.field_reference + "' => $row['" + reference.field_reference + "']));");
                find_references += file;


                ref = true;
            }

            List<Attribute> listattr = model.attributes;
            Collections.sort(listattr, new CustomComparator());
            int ta = listattr.size();
            for (int j = 0; j < ta; j++) {
                Attribute attr = listattr.get(j);
                list_atrrs_select += ", " + attr.name;
                list_atrrs_create_param += "$" + attr.name + ", ";
                list_atrrs_create += attr.name + ", ";
                list_atrrs_create_values += ":" + attr.name + ", ";
                list_atrrs_create_bind += "\t\t"+"$stmt->bindParam(\"" + attr.name + "\", $" + this.setPluralize(model.name).toLowerCase() + "->" + attr.name + ");\n";
                list_atrrs_update += attr.name + " = :" + attr.name + ", ";
                list_atrrs_update_bind += "$stmt->bindParam(\"" + attr.name + "\", $" + this.setPluralize(model.name).toLowerCase() + "->" + attr.name + ");\n";
                query_select_param_model += ", " + this.setPluralize(model.name).toLowerCase() + "." + attr.name + " " + this.setPluralize(model.name).toLowerCase() + attr.name;
                query_select_param_model_array += ", '" + attr.name + "' => $row['" + this.setPluralize(model.name).toLowerCase() + attr.name + "']";


            }

            query_select_param_model = this.setPluralize(model.name).toLowerCase() + ".id " + this.setPluralize(model.name).toLowerCase() + "id " + query_select_param_model;
            query_select_param_model_array = "'id' => $row['" + this.setPluralize(model.name).toLowerCase() + "id']" + query_select_param_model_array;
            query_select_param_model_array = "$" + this.setPluralize(model.name).toLowerCase() + " = array(" + query_select_param_model_array + ");\n";

            if (ref) {
                if (tr > 1) {
                    query_select = "SELECT " + query_select_param_model + ", " + query_select_param_references.substring(0, query_select_param_references.length() - 2) + " FROM " + this.setPluralize(model.name).toLowerCase()
                        + query_select_inner_join
                        + " WHERE " + query_select_where.substring(0, query_select_where.length() - 4);
                }else{
                    query_select = "SELECT " + query_select_param_model + ", " + query_select_param_references.substring(0, query_select_param_references.length() - 2) + " FROM " + this.setPluralize(model.name).toLowerCase()
                        + query_select_inner_join
                        + " WHERE " + query_select_where;
                }
                
            } else {
                query_select = "SELECT " + query_select_param_model + " FROM " + this.setPluralize(model.name).toLowerCase();
            }





            listattr = model.attributes;
            Collections.sort(listattr, new CustomComparator());
            ta = listattr.size();
            for (int j = 0; j < ta; j++) {
                Attribute attr = listattr.get(j);

                if (attr.field.equals("true")) {

                    if (ref) {
                        Reference reference = this.isKey(model.name, attr.name);
                        if (reference == null) {
                            query_select_find = "SELECT " + query_select_param_model + ", " + query_select_param_references + " FROM " + this.setPluralize(model.name).toLowerCase()
                                    + query_select_inner_join
                                    + " WHERE " + query_select_where + " AND " + this.setPluralize(model.name).toLowerCase() + "." + attr.name + " LIKE '%$" + attr.name + "%' LIMIT $from, $to";
                        } else {
                            query_select_find = "SELECT " + query_select_param_model + ", " + query_select_param_references + " FROM " + this.setPluralize(model.name).toLowerCase()
                                    + query_select_inner_join
                                    + " WHERE " + query_select_where + " AND " + this.setPluralize(reference.model_reference).toLowerCase() + "." + reference.field_reference + " LIKE '%$" + attr.name + "%' LIMIT $from, $to";
                        }








                    } else {
                        query_select_find = "SELECT " + query_select_param_model + " FROM " + this.setPluralize(model.name).toLowerCase() + " WHERE " + this.setPluralize(model.name).toLowerCase() + "." + attr.name + " LIKE '%$" + attr.name + "%' LIMIT $from, $to";
                    }


                    String file = readStreamTpl("_find.tpl");
                    file = file.replace("//nameclass//", this.setPluralize(model.name).toLowerCase());
                    file = file.replace("//nameclass_pluralize//", this.setPluralize(model.name).toLowerCase());
                    file = file.replace("//namefunction//", this.setSingularize(attr.name));
                    file = file.replace("//name//", attr.name);
                    file = file.replace("//query_select//", query_select_find);
                    file = file.replace("//query_select_param_references_array//", query_select_param_references_array);
                    file = file.replace("//query_select_param_model_array//", query_select_param_model_array);
                    file = file.replace("//query_select_param_references_post//", query_select_param_references_post);
                    list_atrrs_find += file;
                }
            }

            String file = readStreamTpl("m_model.php.tpl");
            file = file.replace("//NAMECLASS//", model.name);
            file = file.replace("//nameclass//", this.setPluralize(model.name).toLowerCase());
            file = file.replace("//nameclass_pluralize//", this.setPluralize(model.name).toLowerCase());
            file = file.replace("//list_atrrs_select//", list_atrrs_select);
            file = file.replace("//list_atrrs_create_param//", list_atrrs_create_param.substring(0, list_atrrs_create_param.length() - 2));
            file = file.replace("//list_atrrs_create//", list_atrrs_create.substring(0, list_atrrs_create.length() - 2));
            file = file.replace("//list_atrrs_create_values//", list_atrrs_create_values.substring(0, list_atrrs_create_values.length() - 2));
            file = file.replace("//list_atrrs_create_bind//", list_atrrs_create_bind);
            file = file.replace("//list_atrrs_update_bind//",  list_atrrs_update_bind);
            
            file = file.replace("//list_atrrs_update//", list_atrrs_update.substring(0, list_atrrs_update.length() - 2));
            file = file.replace("//list_atrrs_find//", list_atrrs_find);
            file = file.replace("//query_select//", query_select);
            file = file.replace("//query_select_param_references_array//", query_select_param_references_array);
            file = file.replace("//query_select_param_model_array//", query_select_param_model_array);
            file = file.replace("//query_select_param_references_post//", query_select_param_references_post);
            file = file.replace("//find_references//", find_references);
            file = file.replace("//NAMECLASS_SINGULARIZE//", this.setSingularize(model.name));
            file = file.replace("//NAMECLASS_PLURALIZE//", this.setPluralize(model.name));




            createfile("/webservices/models/" + model.name.toLowerCase() + "_model.php", path, file);
        }
    }

    public class CustomComparator implements Comparator<Attribute> {

        @Override
        public int compare(Attribute o1, Attribute o2) {
            return Integer.parseInt(o1.item) - Integer.parseInt(o2.item);
            //return o1.item.compareTo(o2.item);
        }
    }
}